home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 008 / src / hack.engrave.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  6KB  |  277 lines

  1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  2. /* hack.engrave.c version 1.0.1 -
  3.     corrected bug in rest_engravings(),
  4.     added make_engr_at() */
  5. #include    "hack.h"
  6. extern char *nomovemsg;
  7. extern char nul[];
  8. struct engr {
  9.     struct engr *nxt_engr;
  10.     char *engr_txt;
  11.     xchar engr_x, engr_y;
  12.     unsigned engr_lth;    /* for save & restore; not length of text */
  13.     long engr_time;    /* moment engraving was (will be) finished */
  14.     xchar engr_type;
  15. #define    DUST    1
  16. #define    ENGRAVE    2
  17. #define    BURN    3
  18. } *head_engr;
  19.  
  20. struct engr *
  21. engr_at(x,y) register xchar x,y; {
  22. register struct engr *ep = head_engr;
  23.     while(ep) {
  24.         if(x == ep->engr_x && y == ep->engr_y)
  25.             return(ep);
  26.         ep = ep->nxt_engr;
  27.     }
  28.     return((struct engr *) 0);
  29. }
  30.  
  31. sengr_at(s,x,y) register char *s; register xchar x,y; {
  32. register struct engr *ep = engr_at(x,y);
  33. register char *t;
  34. register int n;
  35.     if(ep && ep->engr_time <= moves) {
  36.         t = ep->engr_txt;
  37. /*
  38.         if(!strcmp(s,t)) return(1);
  39. */
  40.         n = strlen(s);
  41.         while(*t) {
  42.             if(!strncmp(s,t,n)) return(1);
  43.             t++;
  44.         }
  45.     }
  46.     return(0);
  47. }
  48.  
  49. wipe_engr_at(x,y,cnt) register xchar x,y,cnt; {
  50. register struct engr *ep = engr_at(x,y);
  51. register int lth,pos;
  52. char ch;
  53.     if(ep){
  54.         if(ep->engr_type != DUST) {
  55.             cnt = rn2(1 + 50/(cnt+1)) ? 0 : 1;
  56.         }
  57.         lth = strlen(ep->engr_txt);
  58.         if(lth && cnt > 0 ) {
  59.             while(cnt--) {
  60.                 pos = rn2(lth);
  61.                 if((ch = ep->engr_txt[pos]) == ' ')
  62.                     continue;
  63.                 ep->engr_txt[pos] = (ch != '?') ? '?' : ' ';
  64.             }
  65.         }
  66.         while(lth && ep->engr_txt[lth-1] == ' ')
  67.             ep->engr_txt[--lth] = 0;
  68.         while(ep->engr_txt[0] == ' ')
  69.             ep->engr_txt++;
  70.         if(!ep->engr_txt[0]) del_engr(ep);
  71.     }
  72. }
  73.  
  74. read_engr_at(x,y) register int x,y; {
  75. register struct engr *ep = engr_at(x,y);
  76.     if(ep && ep->engr_txt[0]) {
  77.         switch(ep->engr_type) {
  78.         case DUST:
  79.         pline("Something is written here in the dust.");
  80.         break;
  81.         case ENGRAVE:
  82.         pline("Something is engraved here on the floor.");
  83.         break;
  84.         case BURN:
  85.         pline("Some text has been burned here in the floor.");
  86.         break;
  87.         default:
  88.         pline("Something is written in a very strange way.");
  89.         impossible();
  90.         }
  91.         pline("You read: \"%s\".", ep->engr_txt);
  92.     }
  93. }
  94. make_engr_at(x,y,s)
  95. register int x,y;
  96. register char *s;
  97. {
  98.     register struct engr *ep;
  99.  
  100.     if(ep = engr_at(x,y))
  101.         del_engr(ep);
  102.     ep = (struct engr *)
  103.         alloc((unsigned)(sizeof(struct engr) + strlen(s) + 1));
  104.     ep->nxt_engr = head_engr;
  105.     head_engr = ep;
  106.     ep->engr_x = x;
  107.     ep->engr_y = y;
  108.     ep->engr_txt = (char *)(ep + 1);
  109.     (void) strcpy(ep->engr_txt, s);
  110.     ep->engr_time = 0;
  111.     ep->engr_type = DUST;
  112.     ep->engr_lth = strlen(s) + 1;
  113. }
  114.  
  115. doengrave(){
  116. register int len;
  117. register char *sp;
  118. register struct engr *ep, *oep = engr_at(u.ux,u.uy);
  119. char buf[BUFSZ];
  120. xchar type;
  121. int spct;        /* number of leading spaces */
  122. register struct obj *otmp;
  123.     multi = 0;
  124.     if(u.uswallow) {
  125.         pline("You're joking. Hahaha!");    /* riv05!a3 */
  126.         return(0);
  127.     }
  128.  
  129.     /* one may write with finger, weapon or wand */
  130.     otmp = getobj("#-)/", "write with");
  131.     if(!otmp) return(0);
  132.     if(otmp == (struct obj *)(1))
  133.         type = DUST;
  134.     else if(otmp->otyp == WAN_FIRE && otmp->spe) {
  135.         type = BURN;
  136.         otmp->spe--;
  137.     } else if(otmp->otyp == DAGGER || otmp->otyp == TWO_HANDED_SWORD ||
  138.         otmp->otyp == CRYSKNIFE ||
  139.         otmp->otyp == LONG_SWORD || otmp->otyp == AXE){
  140.         type = ENGRAVE;
  141.         if((int)otmp->spe <= -3) {
  142.             type = DUST;
  143.             pline("Your %s too dull for engraving.",
  144.                 aobjnam(otmp, "are"));
  145.             if(oep && oep->engr_type != DUST) return(1);
  146.         }
  147.     } else    type = DUST;
  148.     if(Levitation && type != BURN){        /* riv05!a3 */
  149.         pline("You can't reach the floor!");
  150.         return(1);
  151.     }
  152.     if(oep && oep->engr_type == DUST){
  153.           pline("You wipe out the message that was written here.");
  154.           del_engr(oep);
  155.           oep = 0;
  156.     }
  157.     if(type == DUST && oep){
  158.     pline("You cannot wipe out the message that is %s in the rock.",
  159.             (oep->engr_type == BURN) ? "burned" : "engraved");
  160.           return(1);
  161.     }
  162.  
  163.     pline("What do you want to %s on the floor here? ",
  164.       (type == ENGRAVE) ? "engrave" : (type == BURN) ? "burn" : "write");
  165.     getlin(buf);
  166.     clrlin();
  167.     spct = 0;
  168.     sp = buf;
  169.     while(*sp == ' ') spct++, sp++;
  170.     len = strlen(sp);
  171.     if(!len) {
  172.         if(type == BURN) otmp->spe++;
  173.         return(0);
  174.     }
  175.     
  176.     switch(type) {
  177.     case DUST:
  178.     case BURN:
  179.         if(len > 15) {
  180.             multi = -(len/10);
  181.             nomovemsg = "You finished writing.";
  182.         }
  183.         break;
  184.     case ENGRAVE:
  185.         {    int len2 = (otmp->spe + 3) * 2 + 1;
  186.             char *bufp = doname(otmp);
  187.             if(digit(*bufp))
  188.                 pline("Your %s get dull.", bufp);
  189.             else {
  190.                 if(!strncmp(bufp,"a ",2))
  191.                     bufp += 2;
  192.                 else if(!strncmp(bufp,"an ",3))
  193.                     bufp += 3;
  194.                 pline("Your %s gets dull.", bufp);
  195.             }
  196.             if(len2 < len) {
  197.                 len = len2;
  198.                 sp[len] = 0;
  199.                 otmp->spe = -3;
  200.                 nomovemsg = "You cannot engrave more.";
  201.             } else {
  202.                 otmp->spe -= len/2;
  203.                 nomovemsg = "You finished engraving.";
  204.             }
  205.             multi = -len;
  206.         }
  207.         break;
  208.     }
  209.     if(oep) len += strlen(oep->engr_txt) + spct;
  210.     ep = (struct engr *) alloc((unsigned)(sizeof(struct engr) + len + 1));
  211.     ep->nxt_engr = head_engr;
  212.     head_engr = ep;
  213.     ep->engr_x = u.ux;
  214.     ep->engr_y = u.uy;
  215.     sp = (char *)(ep + 1);    /* (char *)ep + sizeof(struct engr) */
  216.     ep->engr_txt = sp;
  217.     if(oep) {
  218.         (void) strcpy(sp, oep->engr_txt);
  219.         (void) strcat(sp, buf);
  220.         del_engr(oep);
  221.     } else
  222.         (void) strcpy(sp, buf);
  223.     ep->engr_lth = len+1;
  224.     ep->engr_type = type;
  225.     ep->engr_time = moves-multi;
  226.  
  227.     /* kludge to protect pline against excessively long texts */
  228.     if(len > BUFSZ-20) sp[BUFSZ-20] = 0;
  229.  
  230.     return(1);
  231. }
  232.  
  233. save_engravings(fd) int fd; {
  234. register struct engr *ep = head_engr;
  235.     while(ep) {
  236.         if(!ep->engr_lth || !ep->engr_txt[0]){
  237.             ep = ep->nxt_engr;
  238.             continue;
  239.         }
  240.         bwrite(fd, (char *) & (ep->engr_lth), sizeof(ep->engr_lth));
  241.         bwrite(fd, (char *) ep, sizeof(struct engr) + ep->engr_lth);
  242.         ep = ep->nxt_engr;
  243.     }
  244.     bwrite(fd, (char *) nul, sizeof(unsigned));
  245. }
  246.  
  247. rest_engravings(fd) int fd; {
  248. register struct engr *ep;
  249. unsigned lth;
  250.     head_engr = 0;
  251.     while(1) {
  252.         mread(fd, (char *) <h, sizeof(unsigned));
  253.         if(lth == 0) return;
  254.         ep = (struct engr *) alloc(sizeof(struct engr) + lth);
  255.         mread(fd, (char *) ep, sizeof(struct engr) + lth);
  256.         ep->engr_txt = (char *) (ep + 1);    /* Andreas Bormann */
  257.         ep->nxt_engr = head_engr;
  258.         head_engr = ep;
  259.     }
  260. }
  261.  
  262. del_engr(ep) register struct engr *ep; {
  263. register struct engr *ept;
  264.     if(ep == head_engr)
  265.         head_engr = ep->nxt_engr;
  266.     else {
  267.         for(ept = head_engr; ept; ept = ept->nxt_engr)
  268.             if(ept->nxt_engr == ep) {
  269.                 ept->nxt_engr = ep->nxt_engr;
  270.                 goto fnd;
  271.             }
  272.         pline("Error in del_engr?"); impossible();
  273.     fnd:    ;
  274.     }
  275.     free((char *) ep);
  276. }
  277.